`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2020/09/14 21:52:54
// Design Name: 
// Module Name: WritebackEnabled
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
`include "funct.v"
`include "opcode.v"
`include "rt.v"

module WritebackEnabled(
    input wire [31:0] i_rs_out,
    input wire [31:0] i_rt_out,
//    input wire [31:0] i_inst_addr,
    input wire [31:0] i_inst,
//    input wire [31:0] i_imm32_zero,
//    input wire [31:0] i_imm32_sign,
    
    output wire o_result
    );
    
    wire [5:0] op;
    wire [5:0] funct;
    wire [4:0] rs;
    wire [4:0] rt;
    wire [4:0] rd;
    assign op = i_inst[31:26];
    assign funct = i_inst[5:0];
    assign rs = i_inst[25:21];
    assign rt = i_inst[20:16];
    assign rd = i_inst[15:11];
    
//    wire special_result;
//    assign special_result
//        = funct == `FUNCT_ADD ? 1
//        : 0;
    
    wire regimm_result;
    assign regimm_result
        = rt == `RT_BLTZAL ? $signed(i_rs_out) < 0
        : rt == `RT_BGEZAL ? $signed(i_rs_out) >= 0
        : 0
    ;
    
    assign o_result
        = op == `OP_SPECIAL ?
            ( funct == `FUNCT_MOVN ? i_rt_out != 0
            : funct == `FUNCT_MOVZ ? i_rt_out == 0
            : 1
            )
        : op == `OP_SPECIAL2 ? 1
        : op == `OP_REGIMM ? regimm_result
        : op == `OP_ANDI ? 1
        : op == `OP_XORI ? 1
        : op == `OP_LUI ? 1
        : op == `OP_ADDI ? 1
        : op == `OP_ADDIU ? 1
        : op == `OP_SLTI ? 1
        : op == `OP_SLTIU ? 1
        : op == `OP_LW ? 1
        : op == `OP_JAL ? 1
        : 0
    ;
    
endmodule
